package com.dragon.connector.imServer.initializer;

import com.dragon.connector.imServer.handler.ImExceptionHandler;
import com.dragon.connector.imServer.handler.InformationNotification;
import com.dragon.connector.imServer.handler.LoginRequestHandler;
import com.dragon.protoJo.codec.ProtobufDecoder;
import com.dragon.protoJo.codec.WebsocketProtobufEncoder;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.springframework.stereotype.Service;

import java.util.List;


@Service
public class WebSocketInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();

        // 设置http
        pipeline.addLast(new HttpServerCodec())
                //跨域访问
                //聚合器
                .addLast(new HttpObjectAggregator(1024 * 64))
                // 主要用于处理大数据流，比如一个1G大小的文件如果你直接传输肯定会撑暴jvm内存的; 增加之后就不用考虑这个问题了
                .addLast(new ChunkedWriteHandler())
                // websocket 数据压缩
                .addLast(new WebSocketServerCompressionHandler())
                //netty支持websocket
                .addLast(new WebSocketServerProtocolHandler("/ws",null,true))
                //协议包解码
                .addLast(new MessageToMessageDecoder<WebSocketFrame>() {
                    @Override
                    protected void decode(ChannelHandlerContext channelHandlerContext, WebSocketFrame webSocketFrame, List<Object> list) throws Exception {
                        ByteBuf buf = ((BinaryWebSocketFrame) webSocketFrame).content();
                        list.add(buf);
                        buf.retain();
                    }
                })
                // proto二进制数据解码
                .addLast("deCoder",new ProtobufDecoder())
//                // proto数据编码
//                .addLast("enCoder",new ProtobufEncoder())
                .addLast("websocketEnCoder",new WebsocketProtobufEncoder())
                //登录聊天
                .addLast("login",new LoginRequestHandler())
                // websocket心跳检测
                //.addLast(new HeartBeatServerHandler())
                .addLast("InformationNotification",new InformationNotification())
                .addLast("ImExceptionHandler",new ImExceptionHandler());
    }
}
